'use strict';

import { Animations, AnimationsData, TransitionType } from './config';
import { convertAnimationObjectToKeyframes } from './animationParser';
import { LinearTransition } from './transition/Linear.web';
import { SequencedTransition } from './transition/Sequenced.web';
import { FadingTransition } from './transition/Fading.web';
import { insertWebAnimation } from './domUtils';

// Translate values are passed as numbers. However, if `translate` property receives number, it will not automatically
// convert it to `px`. Therefore if we want to keep exisitng transform we have to add 'px' suffix to each of translate values
// that are present inside transform.
function addPxToTranslate(existingTransform) {
  // @ts-ignore `existingTransform` cannot be string because in that case
  // we throw error in `extractTransformFromStyle`
  const newTransform = existingTransform.map(transformProp => {
    const newTransformProp = {};
    for (const [key, value] of Object.entries(transformProp)) {
      if (key.includes('translate')) {
        // @ts-ignore After many trials we decided to ignore this error - it says that we cannot use 'key' to index this object.
        // Sadly it doesn't go away after using cast `key as keyof TransformProperties`.
        newTransformProp[key] = `${value}px`;
      } else {
        // @ts-ignore same as above.
        newTransformProp[key] = value;
      }
    }
    return newTransformProp;
  });
  return newTransform;
}

// In order to keep exisitng transform throughout animation, we have to add it to each of keyframe step.
function addExistingTransform(newAnimationData, newTransform) {
  for (const keyframeStepProperties of Object.values(newAnimationData.style)) {
    if (!keyframeStepProperties.transform) {
      // If transform doesn't exist, we add only transform that already exists
      keyframeStepProperties.transform = newTransform;
    } else {
      // We insert existing transformations before ours.
      Array.prototype.unshift.apply(keyframeStepProperties.transform, newTransform);
    }
  }
}

/**
 *  Modifies default animation by preserving transformations that given element already contains.
 *
 * @param animationName - Name of the animation to be modified (e.g. `FadeIn`).
 * @param existingTransform - Transform values that element already contains.
 * @returns Animation parsed to keyframe string.
 */
export function createAnimationWithExistingTransform(animationName, existingTransform, layoutTransition) {
  let newAnimationData;
  if (layoutTransition) {
    newAnimationData = layoutTransition;
  } else {
    if (!(animationName in Animations)) {
      return '';
    }
    newAnimationData = structuredClone(AnimationsData[animationName]);
  }
  const keyframeName = generateNextCustomKeyframeName();
  newAnimationData.name = keyframeName;
  const newTransform = addPxToTranslate(existingTransform);
  addExistingTransform(newAnimationData, newTransform);
  const keyframe = convertAnimationObjectToKeyframes(newAnimationData);
  insertWebAnimation(keyframeName, keyframe);
  return keyframeName;
}
let customKeyframeCounter = 0;
function generateNextCustomKeyframeName() {
  return `REA${customKeyframeCounter++}`;
}

/**
 * Creates transition of given type, appends it to stylesheet and returns keyframe name.
 *
 * @param transitionType - Type of transition (e.g. LINEAR).
 * @param transitionData - Object containing data for transforms (translateX, scaleX,...).
 * @returns Keyframe name that represents transition.
 */
export function TransitionGenerator(transitionType, transitionData, existingTransform) {
  const transitionKeyframeName = generateNextCustomKeyframeName();
  let transitionObject;
  switch (transitionType) {
    case TransitionType.LINEAR:
      transitionObject = LinearTransition(transitionKeyframeName, transitionData);
      break;
    case TransitionType.SEQUENCED:
      transitionObject = SequencedTransition(transitionKeyframeName, transitionData);
      break;
    case TransitionType.FADING:
      transitionObject = FadingTransition(transitionKeyframeName, transitionData);
      break;
  }
  if (existingTransform) {
    return createAnimationWithExistingTransform('', existingTransform, transitionObject);
  }
  const transitionKeyframe = convertAnimationObjectToKeyframes(transitionObject);
  insertWebAnimation(transitionKeyframeName, transitionKeyframe);
  return transitionKeyframeName;
}
//# sourceMappingURL=createAnimation.js.map